package org.csu.mall.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.csu.mall.common.CONSTANT;
import org.csu.mall.common.UniformResponse;
import org.csu.mall.entity.*;
import org.csu.mall.persistence.*;
import org.csu.mall.service.IOrderService;
import org.csu.mall.utils.BigDecimalUtil;
import org.csu.mall.utils.NumberUtil;
import org.csu.mall.utils.PropertiesUtil;
import org.csu.mall.utils.UsernameUtil;
import org.csu.mall.vo.CartProductVO;
import org.csu.mall.vo.CartVO;
import org.csu.mall.vo.OrderVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements IOrderService {
    private Logger logger= LoggerFactory.getLogger(OrderServiceImpl.class);

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ShippingMapper shippingMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PayInfoMapper payInfoMapper;
    @Autowired
    private CartMapper cartMapper;



    @Override
    public UniformResponse<OrderVO> getOrderDetail(BigInteger orderNo) {
        String username = UsernameUtil.getUsername("username");
        String userId = UsernameUtil.getUserId("userid");
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Order order=orderMapper.selectOne(Wrappers.<Order>query().eq("order_no",orderNo));
            if(order==null)
            {
                return UniformResponse.createForErrorMessage("获取订单信息失败");
            }
            OrderVO orderVO=orderToOrderVO(order);
            return UniformResponse.createForSuccess(orderVO);
        }
    }

    @Override
    public UniformResponse payToSaveOrder(Integer shippingId, Integer paymentType) {
        String username = UsernameUtil.getUsername("username");
        Integer userId = Integer.parseInt(UsernameUtil.getUserId("userid"));
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Order order=new Order();
            order.setUserId(userId);
            BigInteger orderNo=new BigInteger(NumberUtil.genOrderNo());
            order.setOrderNo(orderNo);
            if(shippingMapper.selectById(shippingId)==null)
            {
                return  UniformResponse.createForErrorMessage("没有该地址信息");
            }
            order.setShippingId(shippingId);
            order.setPostage(0);
            order.setPaymentType(paymentType);
            BigDecimal payment=new BigDecimal(0);
            CartVO cartVO=getCartVOLimit(userId);
            logger.info(cartVO.toString());
            List<OrderItem> orderItems=new ArrayList<>();
            for (CartProductVO cartProductVO : cartVO.getCartProductVOList()) {
                OrderItem orderItem=new OrderItem();
                orderItem.setUserId(userId);
                orderItem.setOrderNo(orderNo);
                orderItem.setProductId(cartProductVO.getProductId());
                orderItem.setProductName(cartProductVO.getProductName());
                orderItem.setProductImage(cartProductVO.getProductMainImage());
                orderItem.setCurrentPrice(cartProductVO.getProductPrice());
                if (cartProductVO.getQuantity() > productMapper.selectById(cartProductVO.getProductId()).getStock()) {
                    return UniformResponse.createForErrorMessage("库存不足，支付失败");
                }
                orderItem.setQuantity(cartProductVO.getQuantity());
                orderItem.setTotalPrice(cartProductVO.getProductTotalPrice());
                orderItem.setCreateTime(LocalDateTime.now());
                orderItem.setUpdateTime(LocalDateTime.now());
                orderItems.add(orderItem);
                payment = BigDecimalUtil.add(payment.doubleValue(), cartProductVO.getProductTotalPrice().doubleValue());
            }
            if (payment.compareTo(userMapper.selectById(userId).getBalance()) == 1) {
                return UniformResponse.createForErrorMessage("余额不足，支付失败");
            }
            User user = userMapper.selectById(userId);
            user.setBalance(BigDecimalUtil.sub(user.getBalance().doubleValue(), payment.doubleValue()));
            user.setUpdateTime(LocalDateTime.now());
            int rows = userMapper.updateById(user);
            if (rows != 0) {
                order.setPaymentPrice(payment);
                order.setStatus(CONSTANT.OrderStatus.WAITGOODS.getCode());
                order.setCreateTime(LocalDateTime.now());
                order.setUpdateTime(LocalDateTime.now());
                for (OrderItem orderItemOne : orderItems) {
                    orderItemMapper.insert(orderItemOne);
                }
                //支付成功，添加支付信息
                PayInfo payInfo = new PayInfo();
                payInfo.setOrderNo(orderNo);
                payInfo.setPayDetail(CONSTANT.payDetail.goodPay);
                payInfo.setPayPlatform(CONSTANT.PayPlatform.BALANCEPAY);
                payInfo.setPlatformNumber(new String("0"));
                payInfo.setPlatformStatus(new String("支付已完成"));
                payInfo.setUserId(userId);
                payInfo.setCreateTime(LocalDateTime.now());
                payInfo.setUpdateTime(LocalDateTime.now());
                payInfoMapper.insert(payInfo);
                order.setPaymentTime(LocalDateTime.now());
                orderMapper.insert(order);
                QueryWrapper<Cart> query = new QueryWrapper<>();
                query.eq("user_id", userId).eq("checked", CONSTANT.CartItemCheckedStatus.SELECTED.getCode());
                List<Cart> cartList = cartMapper.selectList(query);
                cleanCart(cartList);
                return UniformResponse.createForSuccessMessage("支付成功，订单已生成");
            }
                return UniformResponse.createForErrorMessage("支付失败");
        }
    }

    @Override
    public UniformResponse<String> commitOrder(Integer shippingId, Integer paymentType) {
        String username = UsernameUtil.getUsername("username");
        Integer userId = Integer.parseInt(UsernameUtil.getUserId("userid"));
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            //Order
            Order order=new Order();
            order.setUserId(userId);
            BigInteger orderNo=new BigInteger(NumberUtil.genOrderNo());
            order.setOrderNo(orderNo);
            if(shippingId==null)
            {
                return UniformResponse.createForErrorMessage("地址为空");
            }
            order.setShippingId(shippingId);
            order.setStatus(CONSTANT.OrderStatus.UNPAY.getCode());
            order.setPaymentType(paymentType);
            BigDecimal paymentPrice=new BigDecimal(0);
            CartVO cartVO=getCartVOLimit(userId);
            if(cartVO==null)
            {
                return UniformResponse.createForErrorMessage("购物车中无商品");
            }
            for (CartProductVO cartProductVO:cartVO.getCartProductVOList()) {
                //OrderItem
                OrderItem orderItem=new OrderItem();
                orderItem.setUserId(userId);
                orderItem.setOrderNo(orderNo);
                orderItem.setProductId(cartProductVO.getProductId());
                orderItem.setProductName(cartProductVO.getProductName());
                orderItem.setProductImage(cartProductVO.getProductMainImage());
                orderItem.setCurrentPrice(cartProductVO.getProductPrice());
                Product product=productMapper.selectById(cartProductVO.getProductId());
                if(cartProductVO.getQuantity()>product.getStock())
                {
                    return UniformResponse.createForErrorMessage(String.format("%s商品库存不足",product.getName()));
                }
                orderItem.setQuantity(cartProductVO.getQuantity());
                orderItem.setTotalPrice(cartProductVO.getProductTotalPrice());
                orderItem.setCreateTime(LocalDateTime.now());
                orderItem.setUpdateTime(LocalDateTime.now());
                orderItemMapper.insert(orderItem);
                paymentPrice=BigDecimalUtil.add(paymentPrice.doubleValue(),cartProductVO.getProductTotalPrice().doubleValue());

            }
            order.setPaymentPrice(paymentPrice);
            order.setCreateTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());
            //todo 邮费
            order.setPostage(0);
            orderMapper.insert(order);

            // 清空购物车
            QueryWrapper<Cart> query = new QueryWrapper<>();
            query.eq("user_id", userId).eq("checked", CONSTANT.CartItemCheckedStatus.SELECTED.getCode());
            List<Cart> cartList = cartMapper.selectList(query);
            cleanCart(cartList);

            return UniformResponse.createForSuccessMessage("提交订单成功");
        }
    }

    @Override
    public UniformResponse getMyOrders(Integer pageNum,Integer pageSize) {
        String username = UsernameUtil.getUsername("username");
        String userId = UsernameUtil.getUserId("userid");
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Page<OrderVO> result = new Page<>();
            Page<Order> result_temp=new Page<>();
            result.setCurrent(pageNum);
            result.setSize(pageSize);
            result_temp.setCurrent(pageNum);
            result_temp.setSize(pageSize);
            QueryWrapper<Order> query = new QueryWrapper<>();
//            if(orderStatus==null)
//            {
            query.eq("user_id",userId);
            query.orderByDesc("update_time");
            result_temp=orderMapper.selectPage(result_temp,query);
            List<Order> orderList=result_temp.getRecords();
            List<OrderVO> orderVOList=new ArrayList<>();
            for (Order order : orderList) {
                orderVOList.add(orderToOrderVO(order));
            }
            result.setRecords(orderVOList);
            return UniformResponse.createForSuccess(result);
//            }
//            query.eq("status",orderStatus).eq("user_id",userId).orderByDesc("update_time");
//            result_temp=orderMapper.selectPage(result_temp,query);
//            List<Order> orderList=result_temp.getRecords();
//            List<OrderVO> orderVOList=new ArrayList<>();
//            for (Order order : orderList) {
//                    orderVOList.add(orderToOrderVO(order));
//
//            }
//            result.setTotal(result_temp.getTotal());
//            result.setRecords(orderVOList);
//            return UniformResponse.createForSuccess(result);


        }
    }

    @Override
    public UniformResponse cancelOrder(BigInteger orderNo,Integer orderStatus,Integer pageNum,Integer pageSize) {
        String username = UsernameUtil.getUsername("username");
        Integer userId = Integer.parseInt(UsernameUtil.getUserId("userid"));
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Order order=orderMapper.selectOne(Wrappers.<Order>query().eq("order_no",orderNo));
            User user=userMapper.selectById(userId);
            if(order!=null)
            {
                if(order.getStatus()==CONSTANT.OrderStatus.WAITGOODS.getCode())
                {
                    order.setStatus(CONSTANT.OrderStatus.CANCEL.getCode());
                    order.setCloseTime(LocalDateTime.now());
                    order.setUpdateTime(LocalDateTime.now());
                    orderMapper.updateById(order);
                    List<OrderItem> orderItems=orderItemMapper.selectList(Wrappers.<OrderItem>query().eq("user_id",userId).eq("order_no",orderNo));
                    for (OrderItem orderItem:orderItems) {
                        Product product=productMapper.selectById(orderItem.getProductId());
                        product.setStock(orderItem.getQuantity());
                        product.setUpdateTime(LocalDateTime.now());
                        productMapper.updateById(product);
                        
                    }
                    user.setBalance(BigDecimalUtil.add(user.getBalance().doubleValue(),order.getPaymentPrice().doubleValue()));
                    user.setUpdateTime(LocalDateTime.now());
                    userMapper.updateById(user);
                    UniformResponse response=getMyOrders(pageNum,pageSize);
                    return UniformResponse.createForSuccess("取消订单成功",response);
                }
                if(order.getStatus()==CONSTANT.OrderStatus.PAYED.getCode())
                {
                    order.setStatus(CONSTANT.OrderStatus.CANCEL.getCode());
                    order.setCloseTime(LocalDateTime.now());
                    order.setUpdateTime(LocalDateTime.now());
                    orderMapper.updateById(order);
                    user.setBalance(BigDecimalUtil.add(user.getBalance().doubleValue(),order.getPaymentPrice().doubleValue()));
                    user.setUpdateTime(LocalDateTime.now());
                    userMapper.updateById(user);
                    UniformResponse response=getMyOrders(pageNum,pageSize);
                    return UniformResponse.createForSuccess("取消订单成功",response);

                }
                return UniformResponse.createForErrorMessage("取消订单失败");
            }
            return UniformResponse.createForErrorMessage("数据库无该订单,取消失败");
        }
    }

    @Override
    public UniformResponse deleteOrder(BigInteger orderNo,Integer orderStatus,Integer pageNum,Integer pageSize) {
        String username = UsernameUtil.getUsername("username");
        String userId = UsernameUtil.getUserId("userid");
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Order order=orderMapper.selectOne(Wrappers.<Order>query().eq("order_no",orderNo));
            if(order!=null)
            {
                order.setUpdateTime(LocalDateTime.now());
                orderMapper.deleteById(order.getId());
                UniformResponse response=getMyOrders(pageNum,pageSize);
                return UniformResponse.createForSuccess("删除订单成功",response);
            }
            return UniformResponse.createForErrorMessage("数据库无该订单,删除失败");
        }
    }

    @Override
    public UniformResponse confirmGoods(BigInteger orderNo) {
        String username = UsernameUtil.getUsername("username");
        Integer userId = Integer.parseInt(UsernameUtil.getUserId("userid"));
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            Order order=orderMapper.selectOne(Wrappers.<Order>query().eq("order_no",orderNo));
            if(order==null)
            {
                return UniformResponse.createForErrorMessage("订单不存在或已被删除");
            }
            if(order.getStatus()<CONSTANT.OrderStatus.WAITGOODS.getCode())
            {
                return UniformResponse.createForErrorMessage("未发货");
            }
            order.setStatus(CONSTANT.OrderStatus.FINISHED.getCode());
            order.setEndTime(LocalDateTime.now());
            order.setUpdateTime(LocalDateTime.now());
            orderMapper.updateById(order);
            return UniformResponse.createForSuccessMessage("取消成功");
        }
    }


    @Override
    public UniformResponse getOrdersForAdmin(Integer pageNum, Integer pageSize) {
        String username = UsernameUtil.getUsername("username");
        String userId = UsernameUtil.getUserId("userid");
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            if(userMapper.selectById(userId).getRole().equals(CONSTANT.Role.CUSTOMER))
            {
                return UniformResponse.createForErrorMessage("无权限");
            }
            if(userMapper.selectById(userId).getRole().equals(CONSTANT.Role.ADMIN))//商城管理员
            {
                Page<OrderVO> orderVOPage = new Page<>();
                Page<Order> orderPage=new Page<>();
                orderVOPage.setCurrent(pageNum);
                orderVOPage.setSize(pageSize);
                orderPage.setCurrent(pageNum);
                orderPage.setSize(pageSize);
                QueryWrapper<Order> query = new QueryWrapper<>();
                query.orderByDesc("update_time");
                orderPage=orderMapper.selectPage(orderPage,query);
                List<OrderVO> orderVOList=new ArrayList<>();
                if(orderPage.getRecords()!=null){
                    for (Order orderOne:orderPage.getRecords()) {
                        OrderVO orderVO=orderToOrderVO(orderOne);
                        orderVOList.add(orderVO);
                    }
                }
                orderVOPage.setRecords(orderVOList);
                return UniformResponse.createForSuccess(orderVOPage);
            }
            //如果是店铺管理员的话，其获取的订单
            Page<OrderVO> orderVOPage = new Page<>();
            Page<OrderItem> orderItemPage=new Page<>();
            orderVOPage.setCurrent(pageNum);
            orderVOPage.setSize(pageSize);
            orderItemPage.setCurrent(pageNum);
            orderItemPage.setSize(pageSize);
            QueryWrapper<OrderItem> query = new QueryWrapper<>();
            query.groupBy("order_no").orderByDesc("total_price");
            orderItemPage=orderItemMapper.selectPage(orderItemPage,query);
            List<OrderVO> orderVOList=new ArrayList<>();
            if(orderItemPage.getRecords()!=null){
                for (OrderItem orderItemOne:orderItemPage.getRecords()) {
                    OrderVO orderVO=orderItemToOrderVO(orderItemOne);
                    orderVOList.add(orderVO);
                }
            }
            orderVOPage.setRecords(orderVOList);
            return UniformResponse.createForSuccess(orderVOPage);
        }
    }

    @Override
    public UniformResponse send_goods(BigInteger orderNo) {
        String username = UsernameUtil.getUsername("username");
        Integer userId = Integer.parseInt((UsernameUtil.getUserId("userid")));
        if (username == null) {
            return UniformResponse.notLogining();
        } else {
            if (userMapper.selectById(userId).getRole().equals(CONSTANT.Role.CUSTOMER)) {
                return UniformResponse.createForErrorMessage("无权限");
            }
            Order order=orderMapper.selectOne(Wrappers.<Order>query().eq("order_no",orderNo));
            if(order==null)
            {
                return UniformResponse.createForErrorMessage("获取订单信息失败");
            }
            if(order.getStatus()==CONSTANT.OrderStatus.UNPAY.getCode())
            {
                return UniformResponse.createForErrorMessage("用户没付款");
            }

            OrderVO orderVO=orderToOrderVO(order);
            for (OrderItem orderItemOne : orderVO.getOrderItems()) {
                Product product = productMapper.selectById(orderItemOne.getProductId());
                Integer stock = product.getStock() - orderItemOne.getQuantity();
                if(stock<0) {
                    return UniformResponse.createForErrorMessage(String.format("%s库存不足，发货失败",product.getName()));
                }
                product.setStock(stock);
                product.setUpdateTime(LocalDateTime.now());
                productMapper.updateById(product);
            }
            order.setSendTime(LocalDateTime.now());
            order.setStatus(CONSTANT.OrderStatus.WAITGOODS.getCode());
            order.setUpdateTime(LocalDateTime.now());
            orderMapper.updateById(order);
            return UniformResponse.createForSuccess("发货成功");
        }
    }


    private OrderVO orderToOrderVO(Order order)
    {
        OrderVO orderVO=new OrderVO();
        orderVO.setOrderNo(order.getOrderNo());
        orderVO.setStatus(order.getStatus());
        orderVO.setPostage(order.getPostage());
        orderVO.setPaymentType(order.getPaymentType());
        orderVO.setMakeTime(order.getCreateTime());
        orderVO.setPaymentTime(order.getUpdateTime());
        orderVO.setShipping(shippingMapper.selectById(order.getShippingId()));
        List<OrderItem> orderItemList=orderItemMapper.selectList(Wrappers.<OrderItem>query().eq("order_no",order.getOrderNo()));
        BigDecimal paymentPrice = new BigDecimal(0);
        orderVO.setOrderItems(orderItemList);
        for (OrderItem orderItem : orderItemList) {
                paymentPrice = BigDecimalUtil.add(paymentPrice.doubleValue(), orderItem.getTotalPrice().doubleValue());
        }
        orderVO.setPaymentPrice(paymentPrice);
        BigDecimal totalPrice=BigDecimalUtil.add(paymentPrice.doubleValue(),order.getPostage().doubleValue());
        orderVO.setTotalPrice(totalPrice);
        return orderVO;
    }
    private OrderVO orderItemToOrderVO(OrderItem orderItem)
    {
        OrderVO orderVO=new OrderVO();
        orderVO.setOrderNo(orderItem.getOrderNo());
        QueryWrapper<Order> query = new QueryWrapper<>();
        query.eq("order_no",orderItem.getOrderNo());
        Order order=orderMapper.selectOne(query);
        orderVO.setStatus(order.getStatus());
        orderVO.setPostage(order.getPostage());
        orderVO.setPaymentType(order.getPaymentType());
        orderVO.setMakeTime(orderItem.getCreateTime());
        orderVO.setPaymentTime(orderItem.getUpdateTime());
        orderVO.setShipping(shippingMapper.selectById(order.getShippingId()));
        List<OrderItem> orderItemList=new ArrayList<>();
        orderItemList.add(orderItem);
        orderVO.setOrderItems(orderItemList);
        orderVO.setPaymentPrice(orderItem.getTotalPrice());
        return orderVO;
    }
    private CartVO getCartVOLimit(Integer userId){
        CartVO cartVO = new CartVO();

        //获取该用户的购物车列表
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId).eq("checked",CONSTANT.CartItemCheckedStatus.SELECTED.getCode());

        List<Cart> cartList = cartMapper.selectList(queryWrapper);

        BigDecimal cartTotalPrice = new BigDecimal("0");

        List<CartProductVO> cartProductVOList = Lists.newArrayList();

        if(CollectionUtils.isNotEmpty(cartList)){
            for(Cart cartItem : cartList){
                CartProductVO cartProductVO = new CartProductVO();
                cartProductVO.setId(cartItem.getId());
                cartProductVO.setUserId(cartItem.getUserId());
                cartProductVO.setProductId(cartItem.getProductId());

                Product product = productMapper.selectById(cartItem.getProductId());

                if(product != null){
                    cartProductVO.setProductMainImage(product.getMainImage());
                    cartProductVO.setProductName(product.getName());
                    cartProductVO.setProductSubtitle(product.getSubtitle());
                    cartProductVO.setProductStatus(product.getStatus());
                    cartProductVO.setProductPrice(product.getPrice());
                    cartProductVO.setProductStock(product.getStock());

                    int buyLimitCount = 0;

                    if(product.getStock() >= cartItem.getQuantity()){
                        buyLimitCount = cartItem.getQuantity();
                        cartProductVO.setLimitQuantity(CONSTANT.LIMIT_NUM_SUCCESS);
                    }else{
                        buyLimitCount = product.getStock();
                        cartProductVO.setLimitQuantity(CONSTANT.LIMIT_NUM_FAILURE);

                        Cart cartForQuantity = new Cart();
                        cartForQuantity.setId(cartItem.getId());
                        cartForQuantity.setQuantity(buyLimitCount);
                        int rows = cartMapper.updateById(cartForQuantity);
                    }
                    cartProductVO.setQuantity(buyLimitCount);
                    cartProductVO.setProductTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),cartProductVO.getQuantity()));
                    cartProductVO.setProductChecked(cartItem.getChecked());
                }
                if(cartItem.getChecked() == CONSTANT.CartItemCheckedStatus.SELECTED.getCode()){
                    cartTotalPrice = BigDecimalUtil.add(cartTotalPrice.doubleValue(),cartProductVO.getProductTotalPrice().doubleValue());
                }
                cartProductVOList.add(cartProductVO);
            }
            cartVO.setCartTotalPrice(cartTotalPrice);
            cartVO.setCartProductVOList(cartProductVOList);
            cartVO.setAllChecked(this.getAllCheckedStatus(userId));
            cartVO.setImageHost(PropertiesUtil.getProperty("image.server.url"));
        }
        return cartVO;
    }//获取用户购物车选中的物品

    private boolean getAllCheckedStatus(Integer userId){
        if(userId == null){
            return false;
        }
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(("user_id"),userId);
        queryWrapper.eq("checked",2);
        int result = cartMapper.selectCount(queryWrapper);
        return result == 0;
    }

    //清空购物车
    private void cleanCart(List<Cart> cartList){
        for(Cart cart : cartList){
            cartMapper.deleteById(cart.getId());
        }
    }

}
